import re
from random import randint
from django.contrib.auth import login
import json
from django.http import HttpResponseBadRequest, JsonResponse,request
from django.shortcuts import *
import logger
from utils.response_code import RETCODE
# Create your views here.from
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from libs.yuntongxun.sms import CCP
from libs.captcha.captcha import captcha
from users.models import User
from django.contrib.auth import *
from django.contrib.auth.mixins import *
#注册
class RegisterView(View):
    def get(self,request):
        return render(request,'register.html')
    def post(self,request):
        # 1、接收用户数据
        mobile: object = request.POST.get('mobile')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        sms_code = request.POST.get('sms_code')
        if not all([mobile,password,password2,sms_code]):
            return HttpResponseBadRequest('参数不全')

        # 2-2、手机号格式是否正确
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('手机号码格式不正确')
        # 2-3、密码是否符合格式
        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password) or not re.match(r'^[0-9a-zA-Z]{8,20}$', password2):
            return HttpResponseBadRequest('密码长度、格式不正确。长度8-20，必须是数字、字母')
        # 2-4、密码和确认密码是否一致
        if password != password2:
            return HttpResponseBadRequest('两次输入的密码不一致')
        #获取短信验证码
        redis_conn = get_redis_connection()
        redis_sms_code = redis_conn.get('sms:%s' % mobile)
        if redis_sms_code.decode()!=sms_code:
            return HttpResponseBadRequest('短信验证码错误')
        #保存注册信息
        user = User.objects.create_user(username=mobile,mobile=mobile,password=password)
        login(request,user)
        resp = redirect(reverse('home:index'))
        resp.set_cookie('is_login',True)
        resp.set_cookie('login_name',user.username)


        return resp

# 验证码视图
class ImageView(View):
    def get(self,request):
        '''
        步骤：
        1、接收前端传递过来的uuid
        2、判断uuid失分获取到
        3、通过调用captcha来生成图片验证码（返回：图片内容和图片二进制）
        4、将图片内容保存到redis中。uuid作为key，图片内容作为值，同时还需要设置一个过期时间
        5、返回图片给前端:
        param request:
        :return:
        '''
        # 1、接收前端传递过来的uuid
        uuid = request.GET.get('uuid')
        # 2、判断uuid失分获取到
        if uuid is None:
            return HttpResponseBadRequest('没有获取到uuid')
        # 3、通过调用captcha来生成图片验证码（返回：图片内容和图片二进制）
        txt, image = captcha.generate_captcha()
        # 4、将图片内容保存到redis中。uuid作为key，图片内容作为值，同时还需要设置一个过期时间
        redis_conn = get_redis_connection('default')
        # name:数据key，这里采用img前缀：uuid
        # time:300秒后过期
        # value：对应key的值
        redis_conn.setex(name='img:%s' % uuid, time=300, value=txt)
        # 5、返回图片给前端:
        return HttpResponse(image, content_type='image/jpeg')

#短信验证
class SmsCodeView(View):
    def get(self, request):
        '''
                      步骤：
                      1、接收前端传递过来的uuid
                      2、判断uuid失分获取到
                      3、通过调用captcha来生成图片验证码（返回：图片内容和图片二进制）
                      4、将图片内容保存到redis中。uuid作为key，图片内容作为值，同时还需要设置一个过期时间
                      5、返回图片给前端
                      :param request:
                      :return:
              '''

        # 1、接收参数
        mobile = request.GET.get('mobile')
        image_code = request.GET.get('image_code')
        uuid = request.GET.get('uuid')
        #     验证参数是否齐全
        if not all([mobile, image_code, uuid]):
            return JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必要的参数'})

        redis_conn = get_redis_connection()
        # 根据传来的图片uuid，获取reids中的值
        image_code_redis= redis_conn.get('img:%s' % uuid)
        #判断图片验证码是否存在
        if image_code_redis is None:
           return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图片验证码不存在'})
        # 删除图形验证码，避免恶意测试图形验证码
        redis_conn.delete('img:%s' % uuid)
        # 比对图片验证码（全部转为小写） redis中的数据是bytes类型
        if image_code.lower()!=image_code_redis.decode().lower():
            return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '验证码错误'})
        # 发送短信6位数的验证码
        sms_code = '%06d' % randint(0, 999999)
        ccp=CCP()
        # 4、保存短信验证码内容到redis中,保存时间1分钟
        redis_conn.setex('sms:%s' % mobile, 60, sms_code)
        ccp.send_template_sms('13028427825',[sms_code,5],1)
        print(f'验证码是{sms_code}')
        return JsonResponse({'code': RETCODE.OK, 'errmsg': '短信发送成功'})
# 登录视图
class LoginView(View):
    def get(self, request):
        return render(request, 'lojin.html')

    # 登录提交
    def post(self, request):
        '''
        实现思路：
        1、接收提交参数
        2、验证参数
         2-1、手机号码是否符合规则
         2-2、密码是否符合规则
        3、用户认证登录
        4、状态保持
        5、根据用户选择的是否记住登录状态进行判断
        6、设置cookie信息，为首页显示服务
        7、跳转到首页
        :param request:
        :return:
        '''
        # 1、接收提交参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        remember = request.POST.get('remember')
        # 2、验证参数
        # 参数是否齐全
        if not all([mobile, password]):
            return HttpResponseBadRequest('缺少必要参数')
        # 2 - 1、手机号码是否符合规则
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('手机号码格式不正确')
        # 2 - 2、密码是否符合规则
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return HttpResponseBadRequest('密码格式不正确')
        #
        # 3、用户认证登录
        # 采用系统自带的认证方法进行认证
        # 如果用户名和密码正确，会返回user，否则返回None
        # 默认的认证方法是：针对于username字段进行用户名的判断。当前的判断信息是“手机号”，所以我们需要修改一下认证字段。我们需要到User模型中进行修改，等测试出现问题的时候，我们再修改
        return_user = authenticate(mobile=mobile, password=password)
        # 如果账号密码验证通过，那么返回有数据的用户信息，否则返回None
        if return_user is None:
            return HttpResponseBadRequest('用户名或密码错误')
        # 4、状态保持
        login(request, return_user)
        # 5、根据用户选择的是否记住登录状态进行判断
        # 6、设置cookie信息，为首页显示服务
        resp = redirect(reverse('home:index'))
        if remember != 'on':  # 没有记住用户信息
            # 浏览器关闭之后过期
            request.session.set_expiry(0)
            resp.set_cookie('is_login', True)

            resp.set_cookie('login_name', return_user.username)
        else:  # 记住用户信息
            # 默认过期时间。其实使用了全局的过期时间。2周
            request.session.set_expiry(None)
            resp.set_cookie('is_login', True, max_age=24 * 3600 * 14)
            resp.set_cookie('login_name', return_user.username, max_age=24 * 3600 * 14)
        # 7、跳转到首页
        return resp


#退出登录视图
class LogoutView(View):
    def get(self,req):
        #1.清楚session的功能
        logout(req)
        resp = redirect(reverse('home:index'))
        #2.删除cookie的数据
        resp.delete_cookie('is_login')
        resp.delete_cookie(('login_name'))
        #3.跳转到主页
        return resp

#忘记密码
class ForgetPasswordView(View):
    def get(self,request):
        return render(request,'forgetpassword.html')
    def post(self,requset):
        mobile =request.POST.get('mobile')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        sms_code = request.POST.get('sms_code')
        # 2、验证数据
        #     2-1、判断参数是否齐全
        if not all([mobile, password, password2, sms_code]):
            return HttpResponseBadRequest('缺少必要的参数')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
           return HttpResponseBadRequest('手机格式不正确')

        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return HttpResponseBadRequest('密码格式不正确')

        if password != password2:
            return HttpResponseBadRequest('两次密码输入不一致')

        redis_conn = get_redis_connection('default')
        redis_sms_code = redis_conn.get('sms:%s' % mobile)
        if redis_sms_code is None:
            return HttpResponseBadRequest('短信验证码过期')
        if redis_sms_code.decode() != sms_code:
            return HttpResponseBadRequest('验证码错误')
        redis_conn.delete('sms:%s' % mobile)
        userinif= User.objects.get(mobile=mobile)
        userinif.set_password(password)
        userinif.save()
        resp = redirect(reverse('home:lojin'))
        return resp

#用户中心
class UserCenterView(LoginRequiredMixin,View):
    def get(self, request):
        userinfo = request.user#获取已经登陆的用户信息
        uu={
             'username': userinfo.username,
             'mobile': userinfo.mobile,
             'avatar': userinfo.avatar.url if userinfo.avatar else None,
             'user_desc': userinfo.user_desc
        }
        return render(request, 'usercenter.html',context=uu)

    def post(self, request):
        userinfo = request.user
        username= request.POST.get('username')
        user_desc = request.POST.get('desc', userinfo.user_desc)
        avatar = request.FILES.get('avatar')
        # print('......',avatar)


        # 2、将用户参数更新到数据库
        #获取到已经登陆的用户，并且这个用户是orm跟踪的
        userinfo.username = username
        userinfo.user_desc = user_desc
        userinfo.avatar = avatar
        # print('aaaaaaaaaaaaaaaaaaaa',userinfo.avatar)
        userinfo.save()
        resp = redirect(reverse('home:index'))
        resp.set_cookie('lojin_name', userinfo.username)

        return resp


from home.models import *
#博客详细试图
class WriteBlogView(View):

    def get(self, requset):
        contvt = ArticleCategory.objects.all()
        return render(requset, 'writeblog.html',context={'list':contvt})

    def post(self,request):
        avatar = request.FILES.get('avatar')
        title = request.POST.get('title')
        category_id = request.POST.get('category')
        tags = request.POST.get('tags')
        sumary = request.POST.get('sumary')
        content = request.POST.get('content')
        user = request.user

        print('kkkkkkkkkk',title)
        # 2、验证数据
        # 2-1、参数齐全验证
        if not all([avatar, title, category_id, sumary, content]):
            return HttpResponseBadRequest('参数不齐全')

        # 2-2、判断分类id
        try:
            category = ArticleCategory.objects.filter(pk=category_id).first()
        except ArticleCategory.DoesNotExist:
            return HttpResponseBadRequest('没有该分类信息')
        # 3、数据入库
        try:
            Article.objects.create(
                title=title,
                author=user,
                avatar=avatar,
                category=category,
                tags=tags,
                sumary=sumary,
                content=content
            )

        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('发布失败，请稍后重试')
        # 4、跳转到指定页面
        return redirect(reverse('home:index'))



